package pl.webapps.alarmme;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class RingingActivity extends Activity {

    private static final String LOG_TAG = "RingingActivity";
    private MediaPlayer mMediaPlayer;
    private int mAlarmTimeHour;
    private int mAlarmTimeMinute;
    private String mAlarmMessage;
    private String mRepoName;
    private final String SOUND_ALARM_INTRO = "alarm_intro";
    private final String SOUND_ALARM_OUTRO = "alarm_outro";
    private final String SOUND_ALARM_HOUR_TAG = "hh";
    private String mHourSound;
    private String mMinutePart1;
    private String mMinutePart2;
    private List<String> playableElementsList;
    private int mCurrentSound;
    private OnClickListener listener;
    private int mPlayMode;
    private static final boolean ENABLE_OUTRO = false;
    private static final int PLAY_MODE_USER = 201;
    private static final int PLAY_MODE_DEFAULT = 202;
    private static final int PLAY_MODE_STOP = 203;
    private int mSnoozeTime;
    private float mAlarmVolume;
    public static final int DEFAULT_SNOOZE_TIME = 5; // 5 minutes
    public static final int DEFAULT_AUTO_SNOOZE_TIME = 5; // 5 minutes
    public static final int DEFAULT_RINGING_TIME_SEC = 15; // 15 seconds

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mCurrentSound = 0;
        loadPreferences();
        mPlayMode = PLAY_MODE_USER;
        setContentView(R.layout.ringing_layout);
        preparePlayingElements();
        prepareViewElements();
        prepareSoundsList();
        saveCurrentRingingAlarmTime();
        if (!LocalResourcesHandler.checkIfSdCardPresentAndHaveSpace()) {
            Msg.d("RingingActivity.playDefaultRingtone");
            playDefaultRingtone();
        } else {
            Msg.d("RingingActivity.playUserRingtone");
            playUserRingtones();
        }
    }

    private void loadPreferences() {
        mSnoozeTime = PreferencesHandler.loadSnoozeTimeDelta();
        mRepoName = PreferencesHandler.getSongsRepo();
        mAlarmVolume = PreferencesHandler.loadAlarmVolume();
        // TODO load other preferences
        // TODO set auto snooze
        // TOD prepare motion listener
    }

    private void saveCurrentRingingAlarmTime() {
        if (PreferencesHandler.loadRingingAlarm() == null) {
            PreferencesHandler.saveRingingAlarm(mAlarmTimeHour + ":" + mAlarmTimeMinute);
        }
    }

    /**
     * this method is needed to reset the alarm to it's default value after user snoozed the alarm few times
     */
    private void restartMainAlarm() {
        String alarm = PreferencesHandler.loadRingingAlarm();
        if (alarm != null) {
            String[] time = alarm.split(":");
            try {
                int h = Integer.parseInt(time[0]);
                int m = Integer.parseInt(time[1]);
                new AlarmUtils(this).turnOnAlarm(h, m);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        PreferencesHandler.clearRingingAlarm();
    }

    private void prepareViewElements() {
        listener = new OnClickListener() {

            @Override
            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.bt_ringing_cancel :
                        btStopAction();
                        break;
                    case R.id.bt_ringing_snooze :
                        btSnoozeAction(mSnoozeTime);
                        break;
                }
            }
        };
        Button btCancel = (Button) findViewById(R.id.bt_ringing_cancel);
        btCancel.setOnClickListener(listener);
        Button btSnooze = (Button) findViewById(R.id.bt_ringing_snooze);
        btSnooze.setOnClickListener(listener);
        TextView timeLabel = (TextView) findViewById(R.id.text_current_time);
        timeLabel.setText(mAlarmTimeHour + ":" + mAlarmTimeMinute);
        if (mAlarmMessage != null) {
            TextView messageLabel = (TextView) findViewById(R.id.text_alarm_message);
            messageLabel.setText(mAlarmMessage);
        }
    }

    private void preparePlayingElements() {
        mMediaPlayer = new MediaPlayer();
        // mMediaPlayer.setVolume(90, 90);
        mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {

            @Override
            public void onCompletion(MediaPlayer mp) {
                Log.d(LOG_TAG, "onCompletion");
                synchronized (this) {
                    if (mPlayMode == PLAY_MODE_USER) {
                        playNextSound();
                    }
                }
            }
        });
        Bundle bun = getIntent().getExtras();
        mAlarmTimeHour = bun.getInt(AlarmUtils.INTENT_ALARM_TIME_HOUR);
        mAlarmTimeMinute = bun.getInt(AlarmUtils.INTENT_ALARM_TIME_MINUTE);
        mAlarmMessage = bun.getString(AlarmUtils.INTENT_ALARM_MESSAGE);
        mMediaPlayer.setVolume(mAlarmVolume, mAlarmVolume);
        mHourSound = String.valueOf(mAlarmTimeHour);
        prepareMinutesSound();
        Log.d(LOG_TAG, "mHourSound=" + mHourSound + ", mMinutePart1=" + mMinutePart1 + ", mMinutePart2=" + mMinutePart2);
    }

    private void prepareSoundsList() {
        playableElementsList = new ArrayList<String>();
        String temp = LocalResourcesHandler.getSoundFromResource(mRepoName, SOUND_ALARM_INTRO);
        if (temp == null) {
            triggerError(0);
            return;
        }
        playableElementsList.add(temp);
        temp = LocalResourcesHandler.getSoundFromResource(mRepoName, mHourSound + SOUND_ALARM_HOUR_TAG);
        if (temp == null) {
            triggerError(0);
            return;
        }
        playableElementsList.add(temp);
        temp = LocalResourcesHandler.getSoundFromResource(mRepoName, mMinutePart1);
        if (temp == null) {
            triggerError(0);
            return;
        }
        playableElementsList.add(temp);
        if (mMinutePart2 != null) {
            temp = LocalResourcesHandler.getSoundFromResource(mRepoName, mMinutePart2);
            if (temp == null) {
                triggerError(0);
                return;
            }
            playableElementsList.add(temp);
        }
        // enable/disable outro
        if (ENABLE_OUTRO) {
            temp = LocalResourcesHandler.getSoundFromResource(mRepoName, SOUND_ALARM_OUTRO);
            if (temp == null) {
                triggerError(0);
                return;
            }
            playableElementsList.add(temp);
        }
        int i = 0;
        for (Iterator<String> iterator = playableElementsList.iterator(); iterator.hasNext();) {
            String elem = iterator.next();
            Log.d(LOG_TAG, "elem" + i++ + "=" + elem);
        }
    }

    private void prepareMinutesSound() {
        if ((mAlarmTimeMinute > 9 && mAlarmTimeMinute < 21) || mAlarmTimeMinute == 30 || mAlarmTimeMinute == 40
                || mAlarmTimeMinute == 50) {
            mMinutePart1 = String.valueOf(mAlarmTimeMinute);
            mMinutePart2 = null;
        }
        if (mAlarmTimeMinute < 10) {
            mMinutePart1 = "0";
            mMinutePart2 = String.valueOf(mAlarmTimeMinute);
        }
        if (mAlarmTimeMinute > 20 && mAlarmTimeMinute != 30 && mAlarmTimeMinute != 40 && mAlarmTimeMinute != 50) {
            int minPart1 = mAlarmTimeMinute / 10;
            mMinutePart1 = minPart1 + "0"; // i.e. 20, 30, 40, 50
            mMinutePart2 = String.valueOf(mAlarmTimeMinute % 10); // i.e. 0,1,2
        }
    }

    private synchronized void playDefaultRingtone() {
        mPlayMode = PLAY_MODE_DEFAULT;
        try {
            mMediaPlayer.setDataSource(this.getAssets().openFd("default_ringtone.mp3").getFileDescriptor());
            mMediaPlayer.prepare();
            mMediaPlayer.setLooping(true);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mMediaPlayer.start();
    }

    private void playUserRingtones() {
        playNextSound();
    }

    private void triggerError(int errorType) {
        Log.d(LOG_TAG, "triggerError=" + errorType);
        playDefaultRingtone();
    }

    private void playNextSound() {
        if (playableElementsList.size() > 0 && mCurrentSound < playableElementsList.size()) {
            Log.e(LOG_TAG, "playNextSound mCurrentSound=" + mCurrentSound);
            try {
                mMediaPlayer.reset();
                mMediaPlayer.setDataSource(playableElementsList.get(mCurrentSound));
                mCurrentSound = (mCurrentSound + 1) % playableElementsList.size();
                mMediaPlayer.prepare();
                mMediaPlayer.start();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Log.e(LOG_TAG, "playNextSound error no sound to play");
        }
    }

    private void btStopAction() {
        synchronized (this) {
            mPlayMode = PLAY_MODE_STOP;
            mMediaPlayer.pause();
            mMediaPlayer.stop();
            restartMainAlarm();
            this.finish();
        }
    }

    private void btSnoozeAction(int snoozeTime) {
        synchronized (this) {
            mPlayMode = PLAY_MODE_STOP;
            mMediaPlayer.pause();
            mMediaPlayer.stop();
            Calendar alarmDate = Calendar.getInstance();
            new AlarmUtils(this).turnOnAlarm(alarmDate.get(Calendar.HOUR_OF_DAY), alarmDate.get(Calendar.MINUTE) + snoozeTime);
            this.finish();
        }
    }
}
